package com.pic.mgt.syushin.action;

import java.io.File;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

import org.springframework.dao.DataAccessException;

import com.pic.mgt.dao.syushin.ISyushinBucketMgtDao;
import com.pic.mgt.dao.syushin.ISyushinBusinessTargetActionDao;
import com.pic.mgt.dao.syushin.SyushinBucketMgtInfoBean;
import com.pic.mgt.executer.SimpleConfirmationFileMaker;
import com.pic.mgt.file.io.FileOperation;
import com.pic.mgt.log.IgxLog;
import com.pic.mgt.manager.business.ApInfoBean;
import com.pic.mgt.manager.business.BasicBusinessInfoBean;
import com.pic.mgt.manager.business.BusinessManager;
import com.pic.mgt.monitor.parser.ConfirmtaionFileForTxFileParser;
import com.pic.mgt.syushin.executer.bucket.backup.BucketBackup;

// (送多方修改)
public class SyushinBucketResendActionImpl implements SyushinBucketResendAction {
	
	private ISyushinBucketMgtDao syushinBucketMgtDao;
	private ISyushinBusinessTargetActionDao syushinBusinessTargetActionDao;
	private BucketBackup bucketBackup;
	private String syushinBucketOutboxPathStr;
	private File syushinBucketOutboxPath;
	private FileOperation fileOperation;
	// (送多方新增)
	private BusinessManager businessManger;
	
	@Override
	public boolean resendBucket(String bucketFilename) {
		if (null == bucketFilename) {
			// ********************** Log **********************
			IgxLog.messageLog.error(this,
					"Resend bucket failed. Do not provide bucket file name.");
			// ********************** Log **********************
			return false;
		}
		
		// ********************** Log **********************
		IgxLog.messageLog.info(this,
						"Starting resend bucket file '{}'preprocess.",
						bucketFilename);
		// ********************** Log **********************
		
		// 從資料庫找出該 Bucket 資訊
		SyushinBucketMgtInfoBean syushinBucketMgtInfoBean = null;
		try {
			// throws DataAccessException
			syushinBucketMgtInfoBean = this.syushinBucketMgtDao.findSyushinBucketMgtInfoByBucketFilename(bucketFilename);
		} catch (DataAccessException e) {
			// ********************** Log **********************
			IgxLog.messageDetailsLog.error(this, e.getMessage());
			// ********************** Log **********************
			
			// ********************** Log **********************
			IgxLog.messageLog.error(this,
					"SUDA-274 Resending bucket file '{}' preprocess occured a database operation error.",
							bucketFilename);
			// ********************** Log **********************
			return false;
		}
		
		if (null == syushinBucketMgtInfoBean) {
			// ********************** Log **********************
			IgxLog.messageLog.error(this,
							"SUDA-275 Resending bucket file '{}' failed. Becuase can't find bucket record in database.",
							bucketFilename);
			// ********************** Log **********************
			
			return false;
		}
		
		// ------------- 開始做 resned bucket 的處理 ------------------
		
		// 取得該  bucket 檔的備份目錄
		File bucketBackupPath = this.bucketBackup.getBackupBucketPath(syushinBucketMgtInfoBean.getBucketTime());
		
		// 取得備份的 bucket 檔
		File backupBucketFile = new File(bucketBackupPath.getAbsolutePath(),
										 syushinBucketMgtInfoBean.getBucketFilename());
		// 取得備份的 bucket 確認檔
		File backupBucketConfirmationFile = ConfirmtaionFileForTxFileParser.getConfirmationFile(backupBucketFile);
		
		// 將 bucket file 的業務從備份目徑搬移(生產)到 syushin bucket ap 目錄 下 (同時更新資料庫的 creating time)
		// throws IOException, DataAccessException
		try {
			BasicBusinessInfoBean basicBusinessInfoBean =
				this.businessManger.getBasicBusinessInfoBean(syushinBucketMgtInfoBean.getBusinessName());
			if (null == basicBusinessInfoBean) {
				// ********************** Log **********************
				IgxLog.messageLog.error(this,
						"The business '{}' of bucket file '{}' has not existed already.",
						syushinBucketMgtInfoBean.getBusinessName(), bucketFilename);
				// ********************** Log **********************
				return false;
			}
			else {
				List<ApInfoBean> apInfoBeanList = basicBusinessInfoBean.getSyushinBusinessApList();
				synchronized (apInfoBeanList) {
					for (ApInfoBean apInfoBean : apInfoBeanList) {
						copyBucketToSyushinBucketOutbox(backupBucketFile, backupBucketConfirmationFile, apInfoBean);
					}
				}
			}
		} catch (DataAccessException e) {
			// ********************** Log **********************
			IgxLog.messageDetailsLog.error(this, e.getMessage());
			// ********************** Log **********************
			
			// ********************** Log **********************
			IgxLog.messageLog.error(this,
							"SUDA-276 Resending bucket file '{}' preprocess occured a database operation error.",
							bucketFilename);
			// ********************** Log **********************
			
			return false;
		} catch (IOException e) {
			// ********************** Log **********************
			IgxLog.messageDetailsLog.error(this, e.getMessage());
			// ********************** Log **********************
			
			// ********************** Log **********************
			IgxLog.messageLog.error(this,
							"SUDA-277 Resending bucket file '{}' preprocess occured an I/O operation error in copying file step.",
							bucketFilename);
			// ********************** Log **********************
			
			return false;
		}
		
		// ********************** Log **********************
		IgxLog.messageLog.info(this,
						"Resending bucket file '{}'preprocess completed.",
						bucketFilename);
		// ********************** Log **********************
		
		return true;
	}
	
	private void copyBucketToSyushinBucketOutbox(File bucketFile, File confirmationFileForBucketFile, ApInfoBean apInfoBean) throws IOException, DataAccessException {
		// (1) 複製 bucket file
		//     throws IOException
		this.fileOperation.copyFileToFolder(bucketFile, apInfoBean.getApFolder());
		
		// (2) 更新資料庫的 creating time
		//     throws DataAccessException
		this.syushinBusinessTargetActionDao.updateCreatingTimeByFilenameAndApName(
												new Timestamp(new Date().getTime()),
												bucketFile.getName(),
												apInfoBean.getApName());
		
		// (3) 產生 confirmation file for bucket file
		
		// 取得將要產生在 syushin bucket ap outbox 底下的Bucket確認檔
		File confirmationFileForBucketFileUnderBucketOutbox = new File(apInfoBean.getApFolder(),
														  			   confirmationFileForBucketFile.getName());
		// 取得將要產生在 syushin bucket outbox 底下Bucket確認檔的暫存檔
		File confirmationTmpFileForBucketFileUnderBucketOutbox =
			SimpleConfirmationFileMaker.getTmepConfirmationFile(confirmationFileForBucketFileUnderBucketOutbox);
		
		// (3-1) 將 File OK 檔複製到 syushin outbox bucket 底下,並先命名為暫存檔名
		//       throws IOException
		this.fileOperation.copyFileToFile(confirmationFileForBucketFile, confirmationTmpFileForBucketFileUnderBucketOutbox);
		
		// (3-2) 將暫存檔 rename 為正確的確認檔檔名
		//       throws IOException
		this.fileOperation.moveFileToFile(confirmationTmpFileForBucketFileUnderBucketOutbox,
										  confirmationFileForBucketFileUnderBucketOutbox);
	}
	
	// --- getter and setter ---

	public void setSyushinBucketMgtDao(ISyushinBucketMgtDao syushinBucketMgtDao) {
		this.syushinBucketMgtDao = syushinBucketMgtDao;
	}

	public void setBucketBackup(BucketBackup bucketBackup) {
		this.bucketBackup = bucketBackup;
	}

	public void setSyushinBucketOutboxPathStr(String syushinBucketOutboxPathStr) {
		this.syushinBucketOutboxPathStr = syushinBucketOutboxPathStr;
		this.syushinBucketOutboxPath = new File(syushinBucketOutboxPathStr);
	}

	public void setFileOperation(FileOperation fileOperation) {
		this.fileOperation = fileOperation;
	}

	public void setSyushinBusinessTargetActionDao(
			ISyushinBusinessTargetActionDao syushinBusinessTargetActionDao) {
		this.syushinBusinessTargetActionDao = syushinBusinessTargetActionDao;
	}
	
	// (送多方新增)
	public void setBusinessManger(BusinessManager businessManger) {
		this.businessManger = businessManger;
	}

}
